﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using log4net;
using WatiN.Core; 

namespace PlayerStat
{
    class ScrapeGER : ScrapeSite
    {
        WebClient wc = new WebClient();
        static int tempNumber = 1;
        ILog logger;
        private int leagueID = -1;
        private int maxRound = -1; //set the max round in one season

        private string site = @"http://www.kicker.de/";
        private string match_url_template = @"http://www.kicker.de/news/fussball/{0}/spieltag/{1}/{2}-{3}/{4}/0/spieltag.html";
        private string league1 = string.Empty;
        private string league2 = string.Empty;

        public ScrapeGER()
        {
            leagueID = Leagues.GermanID;

            logger = LogManager.GetLogger("scrape");

            if (logger == null)
            {
                throw new Exception("Null Logger");
            }
        }

        public void SetLeague(int nLeagueID)
        {
            switch (leagueID)
            {
                case 11:
                    league1 = "bundesliga";
                    league2 = "1-bundesliga";
                    maxRound = 34;
                    break;
                case 28:
                    league1 = "2bundesliga";
                    league2 = "2-bundesliga";
                    maxRound = 34;
                    break;
                case 29:
                    league1 = "3liga";
                    league2 = "3-liga";
                    maxRound = 38;
                    break;
                default:
                    throw new Exception("Wrong League Number");
            }
        }

        public void SetMaxRound(int nMaxRound)
        {
            maxRound = nMaxRound;
        }

        // The Main Function, scrape webs
        public bool Scrape()
        {
            logger.Debug("#Scrape Germany League# Start");
            HtmlDocument mainDoc = new HtmlDocument();
            HtmlDocument statDoc = new HtmlDocument();

            try
            {
                EventInit evnt = new EventInit(leagueID, maxRound,Leagues.GermanID.ToString());
                string date = string.Empty;
                int round = 0;
                int year = 2007;
                string url = string.Empty;
                while (evnt.GetEventRound(leagueID, out year, out round, out date))
                {
                    logger.DebugFormat("Go to season {0}-{1}, round {2}", year, year + 1, round);

                    // Get one season's match URL
                    url = GetAllMatchURL(year);
                    //url = GetMatchURL(year, round);
                    //url = "E:\\temp\\Germany0809.htm"; //for local test
                    logger.Debug("Download match list.");
                    //wc.DownloadFile(url, @"C:\Scrape\MainIE.html");
                    logger.Debug("Goto match list.");
                    mainDoc.Load(@"C:\Scrape\MainIE.html", Encoding.GetEncoding("ISO-8859-1"));
                    //System.Threading.Thread.Sleep(iHomePageWaitTime);

                    //Get Match Date
                    HtmlNode tbl = null;
                    if (!GetMatchTable(mainDoc.DocumentNode, round, out tbl))
                    {
                        logger.Error("The validated match table is not found. Round:" + round.ToString());
                        continue;
                    }

                    DataTable matches = null;
                    if (!GetMatchList(tbl,year, out matches))
                    {
                        logger.ErrorFormat("Parse the match list of round {0} failed.",round);
                        continue;
                    }

                    foreach (DataRow dr in matches.Rows)
                    {
                        MatchData md = new MatchData();
                        md.LeagueID = this.leagueID;
                        md.MatchRound = round;
                        md.matchTime = (DateTime)dr["MatchTime"];
                        md.home = (string)dr["HomeTeam"];
                        md.homeID = (int)dr["HomeID"];
                        md.away = (string)dr["AwayTeam"];
                        md.awayID = (int)dr["AwayID"];
                        md.match.homeScore = (int)dr["HomeScore"];
                        md.match.awayScore = (int)dr["AwayScore"];

                        if (md.ExistInDB())
                        {
                            md = null;
                            logger.DebugFormat("Data is already scraped into DB.");
                            continue;
                        }

                        logger.Debug("Download match statistic page.");
                        //wc.DownloadFile(site+dr["MatchStatURL"].ToString(), @"C:\Scrape\StatIE.html");
                        logger.DebugFormat("Goto match statistic page.{0}",dr["MatchStatURL"].ToString());
                        statDoc.Load(@"C:\Scrape\StatIE.html", Encoding.GetEncoding("ISO-8859-1"));

                        //statIE.GoTo("e:\\temp\\1860 0-4 Kaiserslautern.htm"); // for local test
                        //statIE.GoTo("e:\\temp\\redcard.htm"); // for local test
                        //System.Threading.Thread.Sleep(iMatchPageWaitTime); // wait a longer time to ensure the table can be loaded correctly

                        // Full Match Stat Scrape, need to implement
                        if (!GetMatchStat(statDoc.DocumentNode, ref md))
                        {
                            logger.ErrorFormat("Error to get statistic in {0} vs {1}", md.home, md.away);
                            continue;
                        }
                        md.SaveToDB();

                    }
                    evnt.NextRound();
                }
                logger.Debug("#Scrape Germany League# End");
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("#Scrape Germany League# Failed: Exception.");
                logger.Error(ex.ToString());
                return false;
            }
            finally
            {
                logger.Debug("#Scrape Germany# Finally");
                wc.Dispose();
                if (statDoc != null)
                {
                    logger.Debug("#Scrape Germany# Close StatIE");
                    statDoc = null;
                }
                if (mainDoc != null)
                {
                    logger.Debug("#Scrape Germany# Close MainIE");
                    mainDoc = null;
                }
            }
        }

        /// <summary>
        /// Get the match URL for the specified round/season
        /// </summary>
        /// <param name="year">season's start year</param>
        /// <param name="round">round no.</param>
        /// <returns>URL</returns>
        public string GetMatchURL(int year, int round)
        {
            logger.Debug("#GetMatchURL# Starts. [PARAM IN]Year:" + year.ToString() + ". Round:" + round.ToString());
            int iNextYear = year + 1;
            string strYear = year.ToString();
            string strNextYear = iNextYear.ToString().Substring(iNextYear.ToString().Length - 2, 2);
            string strURL = string.Format(match_url_template, strYear, strNextYear, round);            
            logger.Debug("#GetAllMatchURL# Ends. [PARAM OUT] URL:" + strURL);

            return strURL;
        }

        /// <summary>
        /// Get the match URL for the all round of specified season
        /// </summary>
        /// <param name="year">season's start year</param>
        /// <returns>URL</returns>
        public string GetAllMatchURL(int year)
        {
            logger.Debug("#GetAllMatchURL# Starts. [PARAM IN]Year:" + year.ToString());

            int iNextYear = year + 1;
            string strYear = year.ToString();
            string strNextYear = iNextYear.ToString().Substring(iNextYear.ToString().Length - 2, 2);
            string strURL = string.Format(match_url_template, league1, league2, strYear, strNextYear, -1);           
            
            logger.Debug("#GetAllMatchURL# Ends. [PARAM OUT] URL:" + strURL);

            return strURL;
        }

        // get the specified round data into mTable
        public bool GetMatchTable(HtmlNode doc, int round, out HtmlNode mTable)
        {
            logger.Debug("#GetMatchTable# Starts. [PARAM IN]Round:" + round.ToString());
            HtmlNodeCollection tables = doc.SelectNodes(".//table[@class='tStat' and @summary='Begegnungen']");
            
            if (tables == null || tables.Count <= round)
            {
                mTable = null;
                logger.Debug("#GetMatchTable# Ends. Return:false.");
                return false;
            }
            else
            {
                mTable = tables[round-1];
                logger.Debug("#GetMatchTable# Ends. Return:true.");
                return true;
            }
            //for (i = 0; tables != null && i < tables.Count; i++)
            //{
            //    t = tables[i];
            //    HtmlNode link = t.SelectSingleNode("./tr[1]/th[1]/link[1]");
            //    if (link == null || link.InnerText != "Anstoß")
            //    {
            //        continue;
            //    }
            //    else
            //    {
            //        if (++iCount >= round)
            //        {
            //            break;
            //        }
            //    }
            //}
            //if (tables == null || i >= tables.Count)
            //{
            //    mTable = null;
            //    logger.Debug("#GetMatchTable# Ends. Return:false.");
            //    return false;
            //}
            //else
            //{
            //    mTable = t;
            //    logger.Debug("#GetMatchTable# Ends. Return:true.");
            //    return true;
            //}
        }

        // Scrape the Matches List of each round
        // drop the parameter of [date], edit by Ryan, 20111108
        public bool GetMatchList(HtmlNode tbl, int seanonStartYear, out DataTable mTable)
        {
            logger.Debug("#GetMatchList# Starts.");

            try
            {
                mTable = new DataTable();
                mTable.Columns.Add("MatchTime", typeof(DateTime));
                mTable.Columns.Add("HomeTeam", typeof(string));
                mTable.Columns.Add("HomeID", typeof(int));
                mTable.Columns.Add("HomeScore", typeof(int));
                mTable.Columns.Add("AwayTeam", typeof(string));
                mTable.Columns.Add("AwayID", typeof(int));
                mTable.Columns.Add("AwayScore", typeof(int));
                mTable.Columns.Add("MatchStatURL", typeof(string));

                DateTime dtPreTime = DateTime.Parse("9999/12/31");

                HtmlNodeCollection rows = tbl.SelectNodes(".//tr");
                if (rows == null)
                {
                    logger.Error("Emtpy match table.");
                    return false;
                }
                foreach (HtmlNode tr in rows)
                {
                    string temp = HtmlEntity.DeEntitize(tr.InnerText);
                    if (!string.IsNullOrWhiteSpace(temp)
                        && temp.IndexOf("Anstoß") == -1) // not the table title row
                    {
                        
                        DataRow dr = mTable.NewRow();

                        DateTime dtMatchTime;
                        string strHomeTeam = "";
                        string strAwayTeam = "";
                        int iHomeScore = -1;
                        int iAwayScore = -1;
                        string strMatchURL = "";

                        HtmlNode tc = tr.SelectSingleNode("./td[2]");
                        if (tc != null && !string.IsNullOrEmpty(tc.InnerText.Trim()))
                        {
                            string strTemp = HtmlEntity.DeEntitize(tc.InnerText);
                            //dtPreTime = Translate.TransGerDateTime(strTemp, 2008);
                            dtPreTime = Translate.TransGerDateTime(strTemp, seanonStartYear);
                            
                        }
                        dtMatchTime = dtPreTime;

                        strHomeTeam = HtmlEntity.DeEntitize(tr.SelectSingleNode("./td[3]").InnerText).Trim();
                        strAwayTeam = HtmlEntity.DeEntitize(tr.SelectSingleNode("./td[5]").InnerText).Trim();

                        string strScore = HtmlEntity.DeEntitize(tr.SelectSingleNode("./td[6]").InnerText).Trim();
                        string[] tempStrs = strScore.Split(':');
                        if (tempStrs.Length < 3)
                        {
                            throw new Exception("Can not parse match score.");
                        }
                        iHomeScore = int.Parse(tempStrs[0].Trim());
                        int idxHalf = tempStrs[1].IndexOf('(');
                        iAwayScore = int.Parse(tempStrs[1].Substring(0,idxHalf).Trim());
                        strMatchURL = HtmlEntity.DeEntitize(tr.SelectSingleNode("./td[7]/a[1]").Attributes["href"].Value);

                        dr["MatchTime"] = dtMatchTime;
                        dr["HomeTeam"] = strHomeTeam;
                        //dr["HomeID"] = GetID(tr.TableCells[1].Links[0].Url);
                        dr["HomeID"] = -1;
                        dr["HomeScore"] = iHomeScore;
                        dr["AwayTeam"] = strAwayTeam;
                        //dr["AwayID"] = GetID(tr.TableCells[3].Links[0].Url);
                        dr["AwayID"] = -1;
                        dr["AwayScore"] = iAwayScore;
                        dr["MatchStatURL"] = strMatchURL;
                        mTable.Rows.Add(dr);
                     }
                }

                logger.Debug("#GetMatchList# Ends. Return:true.");
                return true;
            }
            catch(Exception ex)
            {
                logger.Error("#GetMatchList# Failed: Exception.");
                logger.Error(ex.ToString());
                mTable = null;

                logger.Debug("GetMatchTable Ends. Return:false.");
                return false;
            }
        }
        public int GetID(string str)
        {
            string temp = str.Remove(0, @"http://www.foot-national.com/".Length);
            temp = temp.Remove(temp.IndexOf('-'));
            return int.Parse(temp);
        }

        // Scrape each match's statistic
        public bool GetMatchStat(HtmlNode doc, ref MatchData md)
        {
            logger.Debug("#GetMatchStat# Starts.");
            try
            {
                HtmlNode playerInfoTable = doc.SelectSingleNode("(.//table[@class='tStat'])[1]");
                HtmlNode matchInfoTable = doc.SelectSingleNode("(.//table[@class='tStat'])[2]");

                if (playerInfoTable == null || matchInfoTable == null)
                {
                    throw new Exception("The table of team data is not found");
                }

                //string homeTeamName = playerInfoTable.SelectSingleNode("./tr[1]").InnerText.Trim();
                HtmlNode homeTeamData = playerInfoTable.SelectSingleNode("./tr[2]");
                //string awayTeamName = playerInfoTable.SelectSingleNode("./tr[3]").InnerText.Trim();
                HtmlNode awayTeamData = playerInfoTable.SelectSingleNode("./tr[4]");

                if (false == GetTeamStat(homeTeamData, true, ref md.match, ref md.homeplayers) || // get home team's match statistic
                    false == GetTeamStat(awayTeamData, false, ref md.match, ref md.awayplayers)) // get away team's match statistic
                {
                    logger.Debug("#GetMatchStat# Ends. Return:false.");
                    return false;
                }

                //if (false == GetPlayerStat(matchInfoTable, ref md.match, ref md.homeplayers, ref md.awayplayers)) // get all players' match statistic
                //{
                //    logger.Debug("#GetMatchStat# Ends. Return:false.");
                //    return false;
                //}

                logger.Debug("#GetMatchStat# Ends. Return:true");
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("#GetMatchStat# Failed: Exception");
                logger.Error(ex.ToString());

                logger.Debug("#GetMatchStat# Ends. Return:false.");
                return false;
            }
        }

        public bool GetTeamStat(HtmlNode teamData, bool isHomeTeam, ref MatchStat match, ref Dictionary<int, PlayerStat> players)
        {
            logger.Debug("#GetTeamStat# Starts.");
            return false;
            throw new Exception("incomplete");
            //try
            //{

            //    string strTag1 = "Aufstellung: \r\n\r\n"; // start Lineup
            //    int iTag1Idx = 0;
            //    int iTag1Length = strTag1.Length;

            //    string strTag2 = "Einwechslungen: \r\n"; // sub player
            //    int iTag2Idx = teamData.IndexOf(strTag2);
            //    int iTag2Length = strTag2.Length;

            //    string strTag3 = "Reservebank: \r\n"; // other bench player
            //    int iTag3Idx = teamData.IndexOf(strTag3);
            //    int iTag3Length = strTag3.Length;

            //    string strStartLineupAndMarkings = teamData.Substring(iTag1Idx + iTag1Length, iTag2Idx - iTag1Idx - iTag1Length);
            //    string strSubPlayersAndMarkings = teamData.Substring(iTag2Idx + iTag2Length, iTag3Idx - iTag2Idx - iTag2Length);

            //    string[] separator1 = { " - ", " , ", "\r\n" };
            //    string[] separator2 = { " für ", "\r\n" };
            //    string[] startLineupAndMarkings = strStartLineupAndMarkings.Split(separator1, System.StringSplitOptions.RemoveEmptyEntries);
            //    string[] subPlayersAndMarkings = strSubPlayersAndMarkings.Split(separator2, System.StringSplitOptions.RemoveEmptyEntries);

            //    foreach (string s in startLineupAndMarkings)
            //    {
            //        string str = s.Substring(0, (s.IndexOf('(') != -1) ? s.IndexOf('(') : s.Length).Trim();
            //        int number = GenPlayerNumber();

            //        PlayerStat player = new PlayerStat();
            //        player.playerName = str;
            //        player.isPlayerSub = false;
            //        players.Add(number, player);
            //    }

            //    int iSubCount = 0;
            //    foreach (string s in subPlayersAndMarkings)
            //    {
            //        iSubCount++;
            //        if (iSubCount % 2 != 0) // sub player                   
            //        {
            //            string str = s.Substring(0, (s.IndexOf('(') != -1) ? s.IndexOf('(') : s.Length).Trim();
            //            str = str.Substring(str.IndexOf(". ") + 2, str.Length - str.IndexOf(". ") - 2);
            //            int number = GenPlayerNumber();

            //            PlayerStat player = new PlayerStat();
            //            player.playerName = str;
            //            player.isPlayerSub = true;
            //            players.Add(number, player);
            //            //continue;
            //        }
            //        else // switch out player
            //        {
            //            string str = s.Trim();
            //            foreach (KeyValuePair<int, PlayerStat> kv in players)
            //            {
            //                if (str == kv.Value.playerName)
            //                {
            //                    kv.Value.isSwitchOut = true;
            //                    break;
            //                }
            //            }
            //        }
            //    }

            //    //add Marking Info
            //    foreach (KeyValuePair<int, PlayerStat> kv in players)
            //    {
            //        kv.Value.markID = Marking.GetMarkingID(kv.Value.isPlayerSub, kv.Value.isSwitchOut);
            //    }

            //    logger.Debug("#GetTeamStat# Ends. Return:true.");
            //    return true;
            //}
            //catch (Exception ex)
            //{
            //    logger.Error("#GetTeamStat# Failed: Exception");
            //    logger.Error(ex.ToString());

            //    logger.Debug("#GetTeamStat# Ends. Return:false.");
            //    return false;
            //}
        }

        public bool GetPlayerStat(Table table, ref MatchStat match, ref Dictionary<int, PlayerStat> homeplayers, ref Dictionary<int, PlayerStat> awayplayers)
        {
            logger.Debug("#GetPlayerStat# Starts.");

            try
            {
                int flag = 0;

                foreach (TableRow tr in table.TableRows)
                {
                    if (tr.Text.Trim() == "Torschützen") // scores
                    {
                        flag = 1;
                        continue;
                    }
                    else if (tr.Text.Trim() == "Rote Karten") // red card
                    {
                        flag = 2;
                        continue;
                    }
                    else if (tr.Text.Trim() == "Gelb-Rote Karten") // 2 yellow->red card
                    {
                        flag = 3;
                        continue;
                    }
                    else if (tr.Text.Trim() == "Gelbe Karten") // yellow card
                    {
                        flag = 4;
                        continue;
                    }
                    else if (tr.Text.Trim() == "Besondere Vorkommnisse") // other activities, ignore here
                    {
                        flag = 5;
                        continue;
                    }

                    switch (flag)
                    {
                        case 1://For score player
                            {
                                string[] separator = { "(", ")" };
                                string[] scorePlayers = tr.Text.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);

                                for (int i = 0; i < scorePlayers.Length; i = i + 2)
                                {
                                    string strTemp = scorePlayers[i].Trim();
                                    Regex r = new Regex("[0-9]+:[0-9]+");
                                    Match m = r.Match(strTemp);
                                    string strPlayerName = strTemp.Substring(m.Length).Trim();

                                    bool bPlayerExist = false;

                                    #region Search the score player
                                    foreach (KeyValuePair<int, PlayerStat> kv in homeplayers)
                                    {
                                        if (strPlayerName == kv.Value.playerName)
                                        {
                                            

                                            MinuteStat ms = new MinuteStat();
                                            string strGoalMin = scorePlayers[i + 1].Substring(0, scorePlayers[i + 1].IndexOf('.'));
                                            ms.goalMin = Int32.Parse(strGoalMin);

                                            if (scorePlayers[i + 1].Contains("Eigentor"))  // Own Goal
                                            {
                                                ms.isOwnGoal = true;
                                                kv.Value.owngoal++;
                                                //own goal will not be counted 
                                            }
                                            else
                                            {
                                                ms.isOwnGoal = false;
                                                kv.Value.goal++;
                                            }

                                            ms.name = strPlayerName;
                                            kv.Value.MinStat.Add(ms);

                                            bPlayerExist = true;
                                        }
                                    }

                                    foreach (KeyValuePair<int, PlayerStat> kv in awayplayers)
                                    {
                                        if (true == bPlayerExist)
                                        {
                                            break;
                                        }

                                        if (strPlayerName == kv.Value.playerName)
                                        {
                                            

                                            MinuteStat ms = new MinuteStat();
                                            string strGoalMin = scorePlayers[i + 1].Substring(0, scorePlayers[i + 1].IndexOf('.'));
                                            ms.goalMin = Int32.Parse(strGoalMin);

                                            if (scorePlayers[i + 1].Contains("Eigentor"))  // Own Goal
                                            {
                                                ms.isOwnGoal = true;
                                                kv.Value.owngoal++;
                                            }
                                            else
                                            {
                                                ms.isOwnGoal = false;
                                                kv.Value.goal++;
                                            }

                                            ms.name = strPlayerName;
                                            kv.Value.MinStat.Add(ms);

                                            bPlayerExist = true;
                                        }
                                    }
                                    #endregion
                                }

                                break;

                            }
                        case 2: // For red card
                            {
                                string[] separator = { ": " };
                                string[] redPlayers = tr.Text.Split(separator, System.StringSplitOptions.RemoveEmptyEntries); // 3 elements

                                for (int i = 1; i < redPlayers.Length; i++) // redPlayers.Length = 3
                                {
                                    string[] separator1 = { "(", ")" };
                                    string[] TeamRedPlayers = redPlayers[i].Split(separator1, System.StringSplitOptions.RemoveEmptyEntries);

                                    for (int j = 0; j < TeamRedPlayers.Length; j = j + 2)
                                    {
                                        string strTeamRedPlayer = TeamRedPlayers[j].Substring(TeamRedPlayers[j].IndexOf(',') + 1);
                                        bool bPlayerExist = false;

                                        #region //Search the red card player
                                        foreach (KeyValuePair<int, PlayerStat> kv in homeplayers)
                                        {
                                            if (strTeamRedPlayer == kv.Value.playerName)
                                            {
                                                match.homeRCard++;
                                                kv.Value.redCard = 1;

                                                bPlayerExist = true;
                                            }
                                        }

                                        foreach (KeyValuePair<int, PlayerStat> kv in awayplayers)
                                        {
                                            if (true == bPlayerExist)
                                            {
                                                break;
                                            }

                                            if (strTeamRedPlayer == kv.Value.playerName)
                                            {
                                                match.awayRCard++;
                                                kv.Value.redCard = 1;

                                                bPlayerExist = true;
                                            }
                                        }
                                        #endregion
                                    }
                                }

                                break;
                            }

                        case 3: // For 2 yellow->red card
                            {
                                string[] separator = { ": " };
                                string[] twoYellowPlayers = tr.Text.Split(separator, System.StringSplitOptions.RemoveEmptyEntries); // 3 elements

                                for (int i = 1; i < twoYellowPlayers.Length; i++) // redPlayers.Length = 3
                                {
                                    string[] separator1 = { "(", ")" };
                                    string[] TeamTwoYellowPlayers = twoYellowPlayers[i].Split(separator1, System.StringSplitOptions.RemoveEmptyEntries);

                                    for (int j = 0; j < TeamTwoYellowPlayers.Length; j = j + 2)
                                    {
                                        string strTeamTwoYellowPlayer = TeamTwoYellowPlayers[j].Substring(TeamTwoYellowPlayers[j].IndexOf(',') + 1);
                                        bool bPlayerExist = false;

                                        #region //Search the 2 yellow->red card player
                                        foreach (KeyValuePair<int, PlayerStat> kv in homeplayers)
                                        {
                                            if (true == bPlayerExist)
                                            {
                                                break;
                                            }

                                            if (strTeamTwoYellowPlayer == kv.Value.playerName)
                                            {
                                                match.homeRCard++;
                                                match.homeYCard += 2;
                                                kv.Value.yellowCard = 2;
                                                kv.Value.redCard = 1;

                                                bPlayerExist = true;
                                            }
                                        }

                                        foreach (KeyValuePair<int, PlayerStat> kv in awayplayers)
                                        {
                                            if (true == bPlayerExist)
                                            {
                                                break;
                                            }

                                            if (strTeamTwoYellowPlayer == kv.Value.playerName)
                                            {
                                                match.awayRCard++;
                                                match.awayYCard += 2;
                                                kv.Value.yellowCard = 2;
                                                kv.Value.redCard = 1;

                                                bPlayerExist = true;
                                            }
                                        }
                                        #endregion
                                    }
                                }

                                break;
                            }

                        case 4: // For yellow card
                            {
                                string[] separator = { ": " };
                                string[] yellowPlayers = tr.Text.Split(separator, System.StringSplitOptions.RemoveEmptyEntries); // 3 elements

                                for (int i = 1; i < yellowPlayers.Length; i++) // redPlayers.Length = 3
                                {
                                    string[] separator1 = { "(", ")" };
                                    string[] TeamYellowPlayers = yellowPlayers[i].Split(separator1, System.StringSplitOptions.RemoveEmptyEntries);

                                    for (int j = 0; j < TeamYellowPlayers.Length; j = j + 2)
                                    {
                                        string strTwoYellowPlayer = TeamYellowPlayers[j].Substring(TeamYellowPlayers[j].IndexOf(',') + 1);
                                        bool bPlayerExist = false;

                                        #region //Search the yellow card player
                                        foreach (KeyValuePair<int, PlayerStat> kv in homeplayers)
                                        {
                                            if (true == bPlayerExist)
                                            {
                                                break;
                                            }

                                            if (strTwoYellowPlayer == kv.Value.playerName)
                                            {
                                                match.homeYCard++;
                                                kv.Value.yellowCard = 1;

                                                bPlayerExist = true;
                                            }
                                        }

                                        foreach (KeyValuePair<int, PlayerStat> kv in awayplayers)
                                        {
                                            if (true == bPlayerExist)
                                            {
                                                break;
                                            }

                                            if (strTwoYellowPlayer == kv.Value.playerName)
                                            {
                                                match.awayYCard++;
                                                kv.Value.yellowCard = 1;

                                                bPlayerExist = true;
                                            }
                                        }
                                        #endregion
                                    }
                                }

                                break;
                            }
                        default:
                            continue;
                    }
                }

                logger.Debug("#GetPlayerStat# Ends. Return:true.");
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("#GetPlayerStat# Failed: Exception");
                logger.Error(ex.ToString());

                logger.Debug("#GetPlayerStat# Ends. Return:false.");
                return false;
            }
        }

        public int GenPlayerNumber()
        {
            return ((tempNumber++) % 30);
            //try
            //{
            //    return int.Parse(str);
            //}
            //catch (Exception ex)
            //{
            //    return -1 * ((tempNumber++) % 30);
            //}
        }

    }
}
